/*  File Name	: EngineMonitor.h
 *  Author		: Javie Pong
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-7-1
 *  Description:
 */

#ifndef ENGINEMONITOR_H_
#define ENGINEMONITOR_H_
#include "Monitor.h"
#include "EngineService.h"
#include "Acceptor.h"
#include "SockAcceptor.h"
#include "MonitorSock.h"
#include "EnginePlayer.h"
#include "Poker.h"
#include "Table.h"
#include "Configurator.h"
#include "ComDefine.h"

class MySqlDB;

class EngineMonitor:virtual public Monitor<EngineService>
{
public:
	typedef MonitorAcceptor<EngineMonitor,EngineService> EngineAcceptor;
	typedef MonitorConnector<EngineMonitor,EngineService> GateConnector;
	typedef std::map<long,EngineService*>  EngineServiceMap;
	typedef std::map<int,Table*>	TableMap;
	typedef std::vector<Table*>	TableVec;
	typedef std::map<int,int>	IntMap;
	typedef std::map<int,EngineService*> GateMap;
	typedef std::map<int,EnginePlayer*> EngPlayerMap;

	typedef std::map<std::string,MySqlDB*> DBMap;

	typedef ObjectPool<Table> TablePool;
	typedef ObjectPool<EnginePlayer> PlayerPool;
	typedef ObjectPool<Card> CardPool;
	typedef ObjectPool<Poker> PokerPool;

	struct RoutineTimer:public Timer
	{
		RoutineTimer()
		{
			monitor = NULL;
		}
		virtual int handle_timeout(void);
		EngineMonitor *monitor;
	};

private:
	typedef Monitor<EngineService> super;

public:
	virtual ~EngineMonitor();

	static EngineMonitor *instance(void);

	virtual int init(int line_id,int list_size=10240,int block_size=10240,int pool_size=10240,
			int growth_size=1024,std::string pool_name="EngineMonitor-Msg");
	virtual int start(void);
	virtual int stop(void);

	virtual int run_request_loop(void);
	virtual int run_respond_loop(void);
	void collection_info(void);

	virtual int handle_close(EngineService *es);

	int run_timer_reactor_loop(void);

	static int run_timer_reactor_loop(void *p);

	Reactor *timer_reactor(void);

	int respond_to_gate(int cmd,int gate,int role_id,int error=0,MessageBlock *mb=NULL);

	TablePool &table_pool(void);
	PlayerPool &player_pool(void);
	CardPool &card_pool(void);
	PokerPool &poker_pool(void);

	Table *find_table(int id);
	int assign_table(void);

	int make_up_table_info(MessageBlock *mb);

	int make_up_player_info(MessageBlock *mb);

	int broadcast_to_room(int cmd,MessageBlock *mb);

	int room_id(void);

	std::string room_name(void);

	const Json::Value &cfg(void);

	const int line(void);

	EnginePlayer* find_player(int role_id);
	int bind_player(EnginePlayer *player);
	int unbind_player(int role_id);
	EngPlayerMap &player_map(void);

	EngineService *find_gate(int gate_id);
	int bind_gate(int id,EngineService *es);
	int unbind_gate(int gate_id);

	GateMap &gate_map(void);

	void game_exit_save_data(void);

	std::string db_key(std::string ip,int port);
	MySqlDB *local_db(void);
	MySqlDB *find_db(EnginePlayer *player);

private:
	EngineMonitor();

	int conn_gate(void);

	int register_engine(MessageBlock *mb);

	int process_request(MessageBlock *mb);

	int process_respond(MessageBlock *mb);

	static int table_sort(Table *t1,Table *t2);

	static EngineMonitor *instance_;

	RoutineTimer routine_timer_;

	GateConnector *connector_;
	EngineAcceptor *acceptor_;
	Reactor *timer_reactor_;

	PlayerPool	player_pool_;
	CardPool	card_pool_;
	PokerPool	poker_pool_;
	TablePool	table_pool_;

	EngineServiceMap engineservice_map_;
	TableMap 	table_map_;
	TableVec 	table_vec_;
	EngPlayerMap player_map_;
	GateMap 	gate_map_;

	RT_MUTEX rt_mutex_;

	int line_id_;
	int game_type_;

	DBMap db_map_;

};

#endif /* ENGINEMONITOR_H_ */
